home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 245_01 / lca33.c < prev    next >
Text File  |  1987-10-26  |  10KB  |  333 lines

  1.  
  2. /* (3,3) linear cellular automaton    */
  3. /*                    */
  4. /* Reference:                */
  5. /*                    */
  6. /*    Kenneth E. Perry            */
  7. /*    Abstract Mathematical Art        */
  8. /*    BYTE                */
  9. /*    December, 1986            */
  10. /*    pages 181-192            */
  11.  
  12. /*    Copyright (C) 1987        */
  13. /*    Harold V. McIntosh        */
  14. /*    Gerardo Cisneros S.        */
  15.  
  16. /* G. Cisneros, 4.3.87 */
  17. /* 10 April 1987 - Adapted for second neighbors [HVM] */
  18. /* 25 April 1987 - Collection of sample rules [HVM] */
  19. /* 26 April 1987 - Multiple menus [HVM] */
  20. /* 28 April 1987 - version for XVI Feria de Puebla [HVM] */
  21. /* 16 May 1987 - adapted for (3,2) [HVM] */
  22. /* 23 May 1987 - adapted for (3,3) [HVM] */
  23.  
  24. # include <bdos.h>
  25.  
  26. # define COLGRAF     4  /* graph resolution */
  27. # define T80X25      3  /* text resolution */
  28. # define WHCYMAG     1  /* color quad for normal screen */
  29. # define AL        320  /* array length (screen width) */
  30. # define DS        15  /* number of distinct sums */
  31. # define NX         10    /* number of sample rules */
  32.  
  33. char xrule[] =
  34.  
  35.     "000011201210000"  /* holdover         */
  36.     "000101220120021"  /* class iv        */
  37.     "010000212211100"  /* blue dots        */
  38.     "010020002111002"  /* two worlds    */
  39.     "020000212211100"  /* red dots        */
  40.  
  41.     "020101220001001"  /* class iv-ish    */
  42.     "102111211202020"  /* reds on blue    */
  43.     "110120002222112"  /* strange blotches    */
  44.     "210201000201020"  /* dots on bars    */
  45.     "211220020020222"  /* two bgnds        */    
  46.  
  47.     ;
  48.  
  49. char  xx[4], rule[DS+1];
  50. int   arule[DS], arr1[AL], arr2[AL];
  51.  
  52. main()
  53. {
  54. int c, i, jj, n;
  55. int  more = 'r';
  56.  
  57.     videopalette(WHCYMAG);                /* white/cyan/magenta */
  58.  
  59.     tuto();
  60.     while (!kbdst()) jj=rand();                /* wait for keypress */
  61.     c=kbdin();                        /* ignore it */
  62.     jj=rand()%NX;
  63.     for (i=0; i<DS; i++) rule[i] = xrule[DS*jj+i];    /* random sample rule */
  64.     rule[DS]=0;
  65.     for (i=0; i<AL; i++) {                /* random initial array */
  66.     if (i%4 == 0) c=rand();
  67.     arr1[i]=c%3; c/=3;};
  68.     videomode(T80X25);
  69.     videoscroll(3,0,4,71,0,3);                /* menu on blue background */
  70.     videoscroll(16,0,21,71,0,3);
  71.     xmenu(jj+1);                    /* show initial rule */
  72.  
  73.     while (more!='n') {                    /* execute multiple runs */
  74.     rmenu();
  75.     lmenu();
  76.     while (0<1) {                    /* set up one run */
  77.     c=kbdin();
  78.     if (c=='g') break;                    /* go draw graph */
  79.     if (c=='q') more='n';                /* quit for good */
  80.     if (more=='n') break;
  81.     switch (c) {
  82.         case 'r':                    /* edit rule */    
  83.         xblnk();
  84.         edrule();
  85.         videocursor(0,3,0);
  86.         rmenu();
  87.         break;
  88.         case 'l':                    /* edit cell string */
  89.         xblnk();
  90.         edline();
  91.         videocursor(0,3,0);
  92.         lmenu();
  93.         break;
  94.         case '#':                    /* read stored rule */
  95.         xmenu(NX);
  96.         n=DS*((i=lim(1,numin(0),NX))-1);
  97.         xmenu(i);
  98.         for (i=0; i<DS; i++) rule[i] = xrule[n+i];
  99.         rmenu();
  100.             break;
  101.         case 'u':
  102.         xblnk();
  103.         for (i=0; i<AL; i++) arr1[i]=0;
  104.         arr1[AL/4]=1;
  105.             arr1[AL/2]=2;
  106.             arr1[(3*AL)/4]=1;
  107.         lmenu();
  108.             break;
  109.     case 'x':                    /* random rule */
  110.         xblnk();
  111.             for (i=0; i<DS; i++) {
  112.             if (i%4 == 0) c = rand();
  113.             rule[i] = '0'+(c%3);
  114.             c/=3;
  115.             };
  116.         rmenu();
  117.         break;
  118.     case 'y':                    /* random line */
  119.         xblnk();
  120.         for (i=0; i<AL; i++) {
  121.             if (i%4 == 0) c = rand();
  122.             arr1[i]=c%3;
  123.             c/=3;
  124.             };
  125.             lmenu();
  126.         break;
  127.         default: break;
  128.         };
  129.     };
  130.     if (more=='n') break;
  131.     do {
  132.     evolve(rule);
  133.     videocursor(0,0,0);
  134.     scrstr("More?");
  135.     videocursor(0,0,30);
  136.     scrstr("y/n/cr");
  137.     more=kbdin();
  138.     } while (more=='\015');
  139.     videomode(T80X25);                    /* reset the screen */
  140.     if (more=='n') break;
  141.     };
  142. }    
  143.  
  144. edrule()                        /* edit the rule */
  145. {
  146. char c;
  147. int  i;
  148.  
  149.     videocursor(0,1,6);                    /* get the rule */
  150.     i=0;
  151.     while (i<DS) {
  152.         videoputc(rule[i],2);
  153.         videoputc('\010',1);
  154.         c = kbdin();
  155.         if (c == '\015') break;
  156.         switch (c) {
  157.         case '0':  case '1': case '2':            /* state */
  158.             rule[i++] = c;
  159.             videoputc(c,1);
  160.             break;
  161.         case ' ':                    /* space = advance */
  162.             videoputc(rule[i++],1);
  163.             break;
  164.         case '\010':                    /* backspace */
  165.             if (i==0) break;
  166.             videoputc(rule[i--],1);
  167.             videoputc(c,1);
  168.             videoputc(c,1);
  169.             break;
  170.     default: break;
  171.         };
  172.     };
  173. }
  174.  
  175. edline() {                        /* edit the line */
  176.  
  177. char c;
  178. int  i, j, k, ii, jj;
  179.  
  180.     videocursor(0,16,0);
  181.     scrstr("insert states using 0, 1, 2");
  182.     videocursor(0,17,0);
  183.     scrstr("move cursor with n(north), s(south), e(east), w(west), or");
  184.     videocursor(0,18,0);
  185.     scrstr("with keyboard arrows. Space, backspace move right and left.");
  186.     videocursor(0,19,0);
  187.     scrstr("( seeks left margin, < absolutely, { up one line, [ down one line");
  188.     videocursor(0,20,0);
  189.     scrstr(") seeks right margin, > absolutely, } up one line, ] down one line");
  190.     videocursor(0,21,0);
  191.     scrstr("carriage return exits");
  192.     jj=4;
  193.     ii=1;
  194.     while (0<1) {
  195.     ii=lim(1,ii,40);
  196.     jj=lim(1,jj,8);
  197.     j=jj-1;
  198.     i=ii-1;
  199.     videocursor(0,j+6,i);
  200.     c=kbdin();
  201.     if (c == '\015') {videoscroll(16,0,21,70,0,3); break;};
  202.     switch (c) {
  203.     case '0':  case '1': case '2':                /* enter  state */
  204.         arr1[40*j+i] = c-'0';
  205.     ii++;
  206.     break;
  207.     case 's': case '\012': case '\320':          jj++; break;    /* down - next line */
  208.     case 'n': case '\013': case '\310':          jj--; break;    /* up   - last line */
  209.     case 'e': case '\014': case '\315': case ' ': ii++; break;    /* space = advance  */
  210.     case 'w': case '\010': case '\313':          ii--; break;    /* backspace */
  211.     case '<': ii=1;  jj=1;  break;  /* absolute left */
  212.     case '{': ii=1;  jj--;  break;  /* left one row up */
  213.     case '(': ii=1;         break;  /* left this row */
  214.     case '[': ii=1;  jj++;  break;  /* left next row */
  215.     case '>': ii=40; jj=40; break;  /* absolute right */
  216.     case '}': ii=40; jj--;  break;  /* right one row up */
  217.     case ')': ii=40;        break;  /* right this row */
  218.     case ']': ii=40; jj++;  break;  /* right next row */
  219.     default: break;
  220.         };
  221.     videocursor(0,j+6,0);
  222.     for (k=0; k<40; k++) videoputc('0'+arr1[40*j+k],1);
  223.     };
  224. }
  225.  
  226. evolve(rule)                        /* display a screen of evolution */
  227. char *rule;
  228. {int i, j;
  229.  
  230.     videomode(COLGRAF);                    /* erase the screen */
  231.     videocursor(0,0,0);                    /* top text line */
  232.     scrstr("Rule: ");
  233.     scrstr(rule);
  234.     for (i=0; i<DS; i++) {arule[i]=rule[i]-'0';};
  235.     for (j=8; j<200; j++) videodot(j,AL-1,2);
  236.     for (j=8; j<200; j++) {                /* evolve for 192 generations */
  237.         arr2[0]=arule[arr1[AL-3]+arr1[AL-2]+arr1[AL-1]+arr1[0]+arr1[1]+arr1[2]+arr1[3]];
  238.         arr2[1]=arule[arr1[AL-2]+arr1[AL-1]+arr1[0]+arr1[1]+arr1[2]+arr1[3]+arr1[4]];
  239.         arr2[2]=arule[arr1[AL-1]+arr1[0]+arr1[1]+arr1[2]+arr1[3]+arr1[4]+arr1[5]];
  240.         for (i=3; i<AL-3; i++) arr2[i]=arule[arr1[i-3]+arr1[i-2]+arr1[i-1]+arr1[i]+arr1[i+1]+arr1[i+2]+arr1[i+3]];
  241.         arr2[AL-3]=arule[arr1[AL-6]+arr1[AL-5]+arr1[AL-4]+arr1[AL-3]+arr1[AL-2]+arr1[AL-1]+arr1[0]];
  242.         arr2[AL-2]=arule[arr1[AL-5]+arr1[AL-4]+arr1[AL-3]+arr1[AL-2]+arr1[AL-1]+arr1[0]+arr1[1]];
  243.         arr2[AL-1]=arule[arr1[AL-4]+arr1[AL-3]+arr1[AL-2]+arr1[AL-1]+arr1[0]+arr1[1]+arr1[2]];
  244.         for (i=0; i<AL; i++) {videodot(j,i,arr1[i]); arr1[i]=arr2[i];};
  245.     if (kbdst()) {kbdin(); break;};
  246.         };
  247. }
  248.  
  249. tuto()                            /* tutorial and Help screen */
  250. {
  251.     videomode(T80X25);
  252.     videocursor(0,2,0);
  253.     scrstr("<Copyright (C) 1987 - H.V. McIntosh, G. Cisneros S.>");
  254.     videocursor(0,4,0);
  255.     scrstr("      ******* LIFE in One Dimension *******");
  256.     videocursor(0,6,0);
  257.     scrstr("Three States - Black(0), Cyan(1), Magenta(2).");
  258.     videocursor(0,8,0);
  259.     scrstr("Third neighbors - three on each side, seven altogether.");
  260.     videocursor(0,10,0);
  261.     scrstr("Totalistic transition rule - random, edited, or stored.");
  262.     videocursor(0,12,0);
  263.     scrstr("Initial Cellular Array - r